package com.zcy.util;

import com.espertech.esper.common.client.EPCompiled;
import com.espertech.esper.common.client.EventBean;
import com.espertech.esper.common.client.configuration.Configuration;
import com.espertech.esper.common.client.util.NameAccessModifier;
import com.espertech.esper.common.client.util.SafeIterator;
import com.espertech.esper.compiler.client.CompilerArguments;
import com.espertech.esper.compiler.client.EPCompileException;
import com.espertech.esper.compiler.client.EPCompiler;
import com.espertech.esper.compiler.client.EPCompilerProvider;
import com.espertech.esper.compiler.client.util.EPCompiledIOUtil;
import com.espertech.esper.runtime.client.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;

/**
 * Esper流程抽象构建工具
 */
@Slf4j
public class EsperBuilder {

    private Class[] clazz;

    private final String epl;
    private EPCompiled epCompiled;
    private Configuration configuration;
    private EPRuntime epRuntime;

    public EsperBuilder(String epl, Class... clazz) {
        this.clazz = clazz;
        this.epl = epl;
        if (checkParams()) {
            throw new RuntimeException("Epl can not be null");
        }
    }

    private boolean checkParams() {
        return StringUtils.isEmpty(this.epl);
    }

    public void startCompile() {
        EPCompiler epCompiler = EPCompilerProvider.getCompiler();

        configuration = new Configuration();
        // 是否开启 EPL对象 共享
        configuration.getCompiler().getByteCode().setAccessModifierNamedWindow(NameAccessModifier.PUBLIC);
        for (int i = 0; i < clazz.length; i++) {
            configuration.getCommon().addEventType(clazz[i]);
        }

        CompilerArguments args = new CompilerArguments(configuration);

        try {
            epCompiled = epCompiler.compile(epl, args);
        } catch (EPCompileException e) {
            throw new RuntimeException(e);
        }

        if (false) {
            try {
                File jarFile = new File(EsperBuilder.class.getClassLoader().getResource("jars").toURI());
                EPCompiledIOUtil.write(epCompiled, new File(jarFile.getPath() + "/" + System.currentTimeMillis() + ".jar"));
            } catch (IOException e) {
                e.printStackTrace();
            } catch (URISyntaxException e) {
                e.printStackTrace();
            }
        }
    }

    public EPEventService startDeploy(UpdateListener updateListener) {
        if (configuration == null | epCompiled == null) {
            throw new RuntimeException("请先进行编译");
        }

        epRuntime = EPRuntimeProvider.getDefaultRuntime(configuration);

        // 部署服务
        EPDeploymentService deploymentService = epRuntime.getDeploymentService();

        EPDeployment deploy;
        try {
            deploy = deploymentService.deploy(epCompiled);
        } catch (EPDeployException e) {
            throw new RuntimeException(e);
        }


        String selectName = resolveStatementName();
        if (!StringUtils.isEmpty(selectName)) {
            EPStatement statement = deploymentService.getStatement(deploy.getDeploymentId(), resolveStatementName());
            // 如果想要为某个语句添加监听器，则需要在外层使用@name注解指定名称
            statement.addListener(updateListener);
        }

        log.info("模块名称：{}", deploy.getModuleName());

        return epRuntime.getEventService();
    }

    private String resolveStatementName() {
        String[] epls = epl.split("\n");
        String lastIndexOf = epls[epls.length - 1];

        int sIndex = lastIndexOf.indexOf("(");
        int eIndex = lastIndexOf.indexOf(")");

        return sIndex != -1 && eIndex != -1 ? lastIndexOf.substring(sIndex + 2, eIndex - 1) : null;
    }

}

